package com.woniuxy.commons.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.commons.annotation.RequirePermission;
import com.woniuxy.commons.bean.ResponseResult;
import com.woniuxy.commons.enums.ResponseStatus;
import com.woniuxy.commons.enums.TokenEnum;
import com.woniuxy.commons.service.AuthServer;
import com.woniuxy.commons.util.JWTUtil;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author: 15489  <br/>
 * Date: 2022/3/30:14:33  <br/>
 * Description:鉴权的拦截器
 */
@Component
public class PermissionIntercptor extends HandlerInterceptorAdapter {
    @Resource
    @Lazy //延迟注入
    private AuthServer authServer;

    //    在调用controller 的方法之前执行的代码
//    返回值 为true 表示放行 为false 表示拦截不调用后续的方法
//    拦截器会拦截那些请求  普通请求 静态资源
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        判断当前的请求是否是普通的http请求
        if(handler instanceof HandlerMethod){
            //       1.获取到马上要调用的方法 （controller中的方法）
            HandlerMethod handlerMethod=(HandlerMethod) handler;
            Method method=handlerMethod.getMethod();
            System.out.println(method.getName());
            //       2：判断方法上是否有注解
            if(method.isAnnotationPresent(RequirePermission.class)){
                //        3：如果有则获取到注解的值
                RequirePermission rp=method.getDeclaredAnnotation(RequirePermission.class);

                String perms=rp.value();  //授权
                //        4：通过token redis 得到当前用户的账号
                String token = request.getHeader("authorization");
                System.out.println(token);
                if(token==null || token.length()==0 || token.equals("null") || JWTUtil.verify(token).equals(TokenEnum.TOKEN_BAD)){
//                去登陆
                    ResponseResult<Object> result=new ResponseResult<>();
                    result.setCode(500);
                    result.setMessage("请登录");
                    result.setStatus(ResponseStatus.NO_LOGIN);
                    response.setContentType("application/json;charset=utf-8");
                    String data=new ObjectMapper().writeValueAsString(result);
                    response.getWriter().write(data);
                    return false;
                }
//           token 合法 过期
                String uname=JWTUtil.getUname(token);

//        5：判断openfeign 调用auth 模块中的鉴权方法 参数  账号权限
                ResponseResult<Object> result = authServer.hasPerms(uname, perms);
//                6：根据鉴权的结果决定是否
                if(result.getStatus().equals(ResponseStatus.FAIL)){
//                    没权限
                    response.setContentType("application/json;charset=utf-8");
                    String data=new ObjectMapper().writeValueAsString(result);
                    response.getWriter().write(data);
                    return false;
                }



            }
        }














//        7：根据鉴权的结果 决定是否放行


        return true;
    }
}
